#include <iostream>
#include <unistd.h>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <sys/types.h>
#include <sys/wait.h>

using namespace std;

const int N = 2;
const int NUM = 1024;
void writer(int wfd){
    string s = "Hello, I am a writer!";
    pid_t self = getpid();
    int number = 0;
    char buffer[NUM];
    while (true){
        buffer[0] = '\0';  // 清空字符串缓冲区
        // snprintf用于把printf显示到 显示屏的 信息显示到 buffer字符串流中，同时可以限定大小 是一种安全的写法
        snprintf(buffer, NUM, "%d: %s: %d ", number++, s.c_str(), self);
        // cout << buffer << endl;  // 直观查看写的内容
        write(wfd, buffer, strlen(buffer)); // 向通过写端，向管道中写入数据
        sleep(1); // 休眠1秒
    }
}
void reader(int rfd){
    char buffer[NUM];
    while (true){
        buffer[0] = '\0';  // 清空字符串缓冲区
        ssize_t n = read(rfd, buffer, sizeof(buffer)); // 从管道中读取数据  存到buffer中
        if (n <= 0) break; // 如果读取失败，或者读到文件末尾，退出循环
        buffer[n] = '\0'; // 添加字符串结束符 添加\n 才能打印到显示屏
        cout << "father receive: " << buffer << endl; // 直观查看读的内容
    }
    
}
int main(){
    int pipefd[N] = {0}; 
    int n = pipe(pipefd);

    pid_t pid = fork();
    if (pid == 0){
        close(pipefd[0]); // Close read end in child
        writer(pipefd[1]); // 向writer函数传 写端的文件描述符
        exit(0);
    }
    close(pipefd[1]); // Close write end in parent
    reader(pipefd[0]); // Call reader function  父进程读
    // 关闭管道
    pid_t rid = waitpid(pid, nullptr, 0);  // 等待 pid这个子进程，其它参数都为空
    if (rid < 0)   return 3;  // 如果返回值小于0，表示错误, 即等待子进程失败

    return 0;
}